package org.abratuhi.uradar.modules;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Properties;

import org.abratuhi.uradar.model.URadar;
import org.abratuhi.uradar.model.URadarModule;
import org.abratuhi.uradar.model.URadarModuleModel;
import org.abratuhi.uradar.model.URadarUpdateModule;
import org.abratuhi.uradar.util.ResponseUtil;

/**
 * URadarUpdateModule for Facebook.
 * <p>
 * Designed for answering queries from within Facebook application 'SLRadar' - http://apps.facebook.com/slradar, which request information about user's and
 * user's friends' avatars' position and status in Second Life Universe.
 * <p>
 * Stores the minimum information from Facebook required - Facebook IDs of user and user's friends, having installed the 'SLRadar' application.
 * <p>
 * Contains 2 obligatory tables inherited from parent:
 * <ul>
 *  <li>fb(uradarid, moduleid)
 * 	<li>fb_friends(uradarid, uradarid_friends, visibility)
 * </ul>
 * 
 * @author Alexei Bratuhin
 * @version 1.00
 */
public class URadarModuleFB extends URadarUpdateModule{
	
	/**
	 * Constructor.
	 * <p>
	 * Here are the tables defined, and corresponding MySQL statements run.
	 * @param name			-	not important, is substituted with 'fb' in constructor
	 * @param description	-	not important, is substituted with 'Facebook update module' in constructor
	 * @param props			-	module specific properties, currently not really used
	 * @param connection	-	initialized connection to MySQL DB
	 */
	public URadarModuleFB(String name, String description, Properties props) {
		// super
		super("fb", "Facebook update module", props);
		// custom
		// specify the corresponding table
		// fb
		String fb_name = "fb";
		String[] fb_fieldnames = {"uradarid", "moduleid" };
		String[] fb_fieldtypes = {"varchar(100)", "varchar(100)"};
		URadarModuleModel fb_model = new URadarModuleModel(fb_name, fb_fieldnames, fb_fieldtypes);
		// fb_friends
		String fb_friends_name = "fb_friends";
		String[] fb_friends_fieldnames={"uradarid", "uradarid_friend", "visibility"};
		String[] fb_friends_fieldtypes = {"varchar(100)", "varchar(100)", "varchar(100)"};
		URadarModuleModel fb_friends_model = new URadarModuleModel(fb_friends_name, fb_friends_fieldnames, fb_friends_fieldtypes);
		// add
		ArrayList<URadarModuleModel> modelz = new ArrayList<URadarModuleModel>();
		modelz.add(fb_model);
		modelz.add(fb_friends_model);
		this.setModel(modelz);
		// create tables if needed
		if(!this.checkTables()) this.createTables();
	}
	
	/**
	 * Get module-specific information about user from another module.
	 * <p>
	 * Currently supports only getting information from URadarModule for Second Life. In case of requesting another module, request is proceeded in superclass. 
	 * @param reqprops		HTTP GET query
	 * @return				<ul><li>XML-string representing module-specific information about user from another module</li>
	 * 					 	<li>FAIL, if request fails due to existance of 'sl' module not being instance of URadarModuleSL</li></ul>
	 */
	public String getOwnInfoFromModule(Properties reqprops){
		// get request info
		String modulename = reqprops.getProperty("reqmodulefrom");
		String myURadarID = reqprops.getProperty("uradarid");
		// proceed request
		if(modulename.equals("sl")){
			URadarModule module = URadar.getInstance().findModule(modulename);
			if(module != null && (module instanceof URadarModuleSL)){
				return ((URadarModuleSL) module).getOwnInfoWithFB(myURadarID);
			}
			else{
				return FAIL;
			}
		}
		else{
			return super.getOwnInfoFromModule(reqprops);
		}
	}


	/**
	 * Get module-specific information about user's friends.
	 * <p>
	 * Currently supports only getting information from URadarModule for Second Life. In case of requesting another module, request is proceeded in superclass.
	 * @param reqprops		array of friends' URadarIDs
	 * @return				<ul><li>XML-string representing module-specific information about user's friends</li>
	 * 					 	<li>FAIL, if request fails due to existance of 'sl' module not being instance of URadarModuleSL</li></ul>
	 */
	public String getFriendsInfoFromModule(Properties reqprops){
		// get request info
		String modulename = reqprops.getProperty("reqmodulefrom");
		String myURadarID = reqprops.getProperty("uradarid");
		String[] friendsURadarID = super.getFriendsURadarID(myURadarID);
		// proceed request
		if(modulename.equals("sl")){
			URadarModule module = URadar.getInstance().findModule(modulename);
			if(module != null && (module instanceof URadarModuleSL)){
				return ((URadarModuleSL) module).getFriendsInfoWithFB(friendsURadarID);
			}
			else{
				return FAIL;
			}
		}
		else{
			return super.getFriendsInfoFromModule(reqprops);
		}
	}
	
	public String proceedRequest(Properties reqprops){
		// init response string
		String response = new String();
		// get request type
		String reqtype = reqprops.getProperty("reqtype");
		// switch
		if(reqtype.equals("get_own_info_from_module")){
			response = getOwnInfoFromModule(reqprops);
		}
		if(reqtype.equals("get_friends_info_from_module")){
			response = getFriendsInfoFromModule(reqprops);
		}
		// return, pay attention to super
		if(response == null || response == FAIL || response.equals(new String()) || response.length()<1){	// in case URadarModuleFB couldn't proceedrequest itself, ask help from superclass
			response = super.proceedRequest(reqprops);
		}
		
		return response;
	}
	


	public String getOwnInfoWithOS(String myURadarID) {
		// init return/response string
		String out = new String();
		// try to connect to DB for search
		try{
			Connection connection = openConnection();
			
			// create statement
			Statement stmt = connection.createStatement();
			
			// generate query string
			String sql_get_own_info = 	"select os.uradarid, os.moduleid as osid, fb.moduleid as fbid " +
										"from os inner join fb on os.uradarid = fb.uradarid " +
										"where os.uradarid='"+myURadarID+"';";
			
			// query DB for own info
			ResultSet rs_get_own_info = stmt.executeQuery(sql_get_own_info);
			
			// generate return/response string
			out = ResponseUtil.convertResultSet2XMLString(rs_get_own_info);
			
			// close statement, garbage collector is not to be relied upon
			stmt.close();
			
			closeConnection(connection);
		} catch (SQLException e){
			e.printStackTrace();
			out = FAIL;
		}
		// return
		return out;
	}

	public String getFriendsInfoWithOS(String[] friendsURadarID) {
		// init return/response string
		String out = new String();
		//	check whether friends array is empty -> send empty response then		
		if(! (friendsURadarID.length > 0)){
			out = ResponseUtil.convertNothing2XMLString();
		}
		else{
			// try to connect to DB for search
			try{
				Connection connection = openConnection();
				
				// create statement
				Statement stmt = connection.createStatement();
				
				// generate query string
				String sql_get_friends_info = "";
				sql_get_friends_info += "select os.uradarid, os.moduleid as osid, fb.moduleid as fbid " +
										"from os inner join fb on os.uradarid = fb.uradarid " +
										"where os.uradarid in ('";
				for(int i=0; i<friendsURadarID.length-1; i++){
					sql_get_friends_info += friendsURadarID[i] + "',' ";
				}
				sql_get_friends_info += friendsURadarID[friendsURadarID.length-1];
				sql_get_friends_info += "');";
				
				// query DB for own info
				ResultSet rs_get_friends_info = stmt.executeQuery(sql_get_friends_info);
				
				// generate return/response string
				out = ResponseUtil.convertResultSet2XMLString(rs_get_friends_info);
				
				// close statement, garbage collector is not to be relied upon
				stmt.close();
				
				closeConnection(connection);
			} catch (SQLException e){
				e.printStackTrace();
				out = FAIL;
			}
		}
		// return
		return out;
	}

}
